using Publicuse.Entity;
using Publicuse.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Publicuse.Entity.sqlsugar;
using SqlSugar;
using Microsoft.Extensions.Configuration;

namespace Publicuse.Autofac
{
    public sealed class AutofacLogUtil
    {
        private static AutofacLogUtil instance;

        private static readonly object loglock = new object();
        private static readonly SqlSugarScope sugarClient;
        static AutofacLogUtil()
        {
            instance = new AutofacLogUtil();
            ConnectionConfig connectionConfig = new ConnectionConfig()
            {
                ConfigId = "MySql",
                DbType = DbType.MySql,
                IsAutoCloseConnection = true,
                ConnectionString = AesEncryptionUtil.AESDecrypt(AppSettingUtil.MySqlSugarConnection, out var msg),
            };
            sugarClient = new SqlSugarScope(connectionConfig);
        }

        public static AutofacLogUtil GetInstance
        {
            get { return instance; }
        }

        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="modulename"></param>
        /// <returns></returns>
        private string CreateDirectory(string initmodule, string modulename)
        {
            modulename = modulename.Replace("-", "\\");
            try
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(initmodule + modulename);
                directoryInfo.Create();
            }
            catch (Exception ex)
            {
                var ss = ex.Message;
            }

            return initmodule + modulename;
        }

        public void WriteLogOld(string module, string content, bool isSuccess)
        {
            var timepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\" + DateTime.Now.ToString("yyyyMMdd");
            timepath = timepath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
            if (!Directory.Exists(timepath))
            {
                Directory.CreateDirectory(timepath);
                WriteLogOld(module, content, isSuccess);
            }
            else
            {
                var filepath = CreateDirectory(timepath + "\\", module);
                filepath = filepath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
                if (!string.IsNullOrEmpty(content))
                {
                    var filetime = isSuccess == true ? "成功" : "失败";
                    var newfilepath = filepath + "\\" + filetime + ".txt";
                    newfilepath = newfilepath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
                    content = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  " + content;
                    WriteLog(newfilepath, content, isSuccess);
                }
            }
        }


        private void WriteLogToDataBase(Log log)
        {
            var aid=sugarClient.Insertable<Log>(log).ExecuteReturnIdentity();
        }


        /// <summary>  
        /// 写入文本  
        /// </summary>  
        /// <param name="content">文本内容</param>  
        private static void Write(string content, string path, bool newLine)
        {
            using (StreamWriter fs = new StreamWriter(path, newLine, Encoding.UTF8))
            {
                fs.WriteLineAsync(content);
            }
        }

        public void WriteDataBase(Log log)
        {
            Task.Run(() => { WriteLogToDataBase(log); });
        }

        private void WriteLog(string path, string content, bool newLine)
        {
            var ink = new Func<string, string, bool, bool>((p, c, n) =>
            {
                Task.Run(() =>
                {
                    WriteContentToFile(p, c, n);
                });
                return true;
            });
            ink.Invoke(path, content, newLine);
        }

        /// <summary>
        /// 写入内容到文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="content"></param>
        private static void WriteContentToFile(string path, string content, bool newLine)
        {
            lock (loglock)
            {
                try
                {
                    Encoding encode = Encoding.UTF8;
                    if (File.Exists(path))
                    {
                        var olddatalength = ReadFileLines(path);
                        if (olddatalength == 0)//文件没有存在内容
                        {
                            using (var file = new FileStream(path, FileMode.OpenOrCreate))
                            {
                                byte[] data = encode.GetBytes(content);
                                file.Write(data, 0, data.Length);
                            }
                        }
                        else//追加内容到原有文件
                        {
                            using (var file = new FileInfo(path).AppendText())
                            {
                                if (newLine)
                                {
                                    if (olddatalength == 1)
                                        file.WriteLine("");

                                    file.WriteLine("");
                                    file.WriteLine(content);
                                }
                                else
                                {
                                    file.Write(content);
                                }
                            }
                        }
                    }
                    else//创建新文件并写入内容
                    {
                        using (var file = new FileStream(path, FileMode.OpenOrCreate))
                        {
                            byte[] data = encode.GetBytes(content);
                            file.Write(data, 0, data.Length);
                        }
                    }
                }
                catch (Exception ex)
                {

                }
            }
        }

        /// <summary>
        /// 读取文件内容长度
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static int ReadFileLines(string path)
        {
            using (var stream = new StreamReader(path, Encoding.UTF8))
            {
                string con = stream.ReadToEnd();
                return con.Length;
            }
        }
    }

    public class TraceHelper
    {
        private static TraceHelper _traceHelper;

        private TraceHelper() { }

        public static TraceHelper GetInstance()
        {
            if (_traceHelper == null)
                _traceHelper = new TraceHelper();

            return _traceHelper;
        }

        public void Error(string message, string module)
        {
            this.Log(message, MessageType.Error, module);
        }

        public void Error(Exception ex, string module)
        {
            this.Log(ex.StackTrace, MessageType.Error, module);
        }

        public void Warning(string message, string module)
        {
            this.Log(message, MessageType.Warning, module);
        }

        public void Info(string message, string module)
        {
            this.Log(message, MessageType.Information, module);
        }

        public void Log(string message, MessageType type, string module)
        {
            Trace.WriteLine(
                string.Format("{0},{1},{2},{3}",
                DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                type.ToString(),
                module,
                message));
        }
    }


    public enum MessageType
    {
        Information = 0,
        Warning = 1,
        Error = 2
    }

    public enum LogModuleType : int
    {
        Wateronsale = 0,
        Bus = 1,
        DB = 2
    }
}
